package com.zhongke.common.http.interceptor;

import android.text.TextUtils;

import com.zhongke.common.utils.ZKGsonUtils;
import com.zhongke.common.utils.ZKRandomUtil;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

/**
 * author : wpt
 * date   : 2021/7/2816:23
 * desc   : 共用参数
 */
public class ZKCommonParamsInterceptor implements Interceptor {


    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {
        Request request = chain.request();
        request = addCommonParam(request);
        Request.Builder builder = request.newBuilder();
        return chain.proceed(builder.build());
    }

    /**
     * 添加共用参数  nonceStr,timestamp
     * nonceStr:随机字符串,长度32位，包含字符0-9a-zA-Z
     * timestamp:10位的秒级时间戳
     *
     * @param request
     * @return
     */
    private Request addCommonParam(Request request) {
        RequestBody requestBody = request.body();
        TreeMap<Object, Object> rootMap = new TreeMap<>();
        // 把原来请求的和公共的参数进行组装
        String nonceStr = ZKRandomUtil.getStrByLength(32);
        rootMap.put("nonceStr", nonceStr);  // 干扰串	32位随机字符串，避免重复
        long timestamp = System.currentTimeMillis() / 1000;
        rootMap.put("timestamp", timestamp + "");  // 10位时间戳,传字符串，避免后面json转map时long数据被转成double导致验签失败

        HttpUrl httpUrl = request.url();
        String method = request.method();
        boolean isGet = method.equals("GET");
        boolean isPost = method.equals("POST");
        boolean isPut = method.equals("PUT");
        boolean isDelete = method.equals("DELETE");
        boolean isPatch = method.equals("PATCH");
        if (isGet || isDelete || isPatch) {
            // 通过请求地址(最初始的请求地址)获取到参数列表
            Set<String> parameterNames = httpUrl.queryParameterNames();
            for (String key : parameterNames) {  // 循环参数列表
                rootMap.put(key, httpUrl.queryParameter(key));
            }
            String newJsonParams = paramToString(rootMap);  // 转换成字符串

            String url = httpUrl.toString();

            int index = url.indexOf("?");
            if (index > 0) {
                url = url.substring(0, index);
            }
            url = url + "?" + newJsonParams;  // 把参数重新到url后面拼接成新的url
            request = request.newBuilder().url(url).build();  // 重新构建请求
        } else if (isPost || isPut) {
            if (requestBody == null) {
                return request;
            }
            try {
                Buffer buffer = new Buffer();
                String newJsonParams = null;
                requestBody.writeTo(buffer);
                String oldParamsJson = buffer.readUtf8();
                if (requestBody instanceof FormBody) {//RequestBody是FormBody  @Field该方式传参
                    String[] splitAnd = oldParamsJson.split("&");
                    for (String str : splitAnd) {
                        String[] splitEqual = str.split("=");
                        for (int i = 0; i < splitEqual.length; i = i + 2) {
                            //value为空时手动传入一个空串
                            rootMap.put(splitEqual[i], splitEqual.length > i + 1 ? splitEqual[i + 1] : "");
                        }
                    }
                    newJsonParams = ZKGsonUtils.getGsonInstance().toJson(rootMap);
                } else if (requestBody instanceof MultipartBody) {//RequestBody是MultipartBody

                } else { //@Body该方式传参
                    //oldParamsJson是有效的json串才执行插入
                    if (!TextUtils.isEmpty(oldParamsJson) && (oldParamsJson.contains("{"))) {
                        String encodeJson = encodeJsonValue(oldParamsJson);
                        //将两个公共参数拼装成  "nonceStr":"lcFwaFkFdXKj1SVXBFj5tM267TgalCuE","timestamp:"1631260778",  的形式
                        String commonParam = TextUtils.concat("\"nonceStr\":\"", nonceStr,
                                "\",\"timestamp\":\"", timestamp + "\",").toString();
                        StringBuilder sb = new StringBuilder(encodeJson);
                        //将上面拼接好的公共参数插入到旧的Json串中
                        sb.insert(encodeJson.indexOf("{") + 1, commonParam);
                        newJsonParams = sb.toString();
                    } else {//参数为空时拼接两个公共参数即可
                        newJsonParams = TextUtils.concat("{\"nonceStr\":\"", nonceStr,
                                "\",\"timestamp\":\"", timestamp + "\"}").toString();
                    }
                }
                RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), newJsonParams);
                request = isPost ? request.newBuilder().url(httpUrl).post(body).build()
                        : request.newBuilder().url(httpUrl).put(body).build();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return request;
    }

    /**
     * 对json串的所有value进行encode
     *
     * @param oldParamsJson
     */
    private String encodeJsonValue(String oldParamsJson) {
        HashMap<Object, Object> hashMap = ZKGsonUtils.getGsonInstance().fromJson(oldParamsJson, HashMap.class);
        Iterator it = hashMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (v != null) {
                hashMap.put(k, URLEncoder.encode(v.toString()));
            }
        }
        return ZKGsonUtils.getGsonInstance().toJson(hashMap);
    }


    /**
     * map参数转为String格式
     *
     * @param parameters
     * @return
     */
    public static String paramToString(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            sb.append(k + "=" + v + "&");
        }
        // 删除最后一个"&"
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }
}
